package cn.edu.hit.mongodb;

import cn.edu.hit.core.Document;
import cn.edu.hit.core.db.DataWriter;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.model.Filters;
import org.bson.types.ObjectId;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;

public class MongoDB implements DataWriter {
    private final MongoCollection<Document> collection;

    public MongoDB(MongoCollection<Document> collection) {
        this.collection = collection;
    }

    @Override
    public Document getById(String _id) {
        return collection.find(Filters.eq("_id", new ObjectId(_id))).first();
    }

    @Override
    public List<Document> queryByTemplate(Map<String, Object> template) {
        if (template.containsKey("_id")) {
            template.put("_id", new ObjectId(template.get("_id").toString()));
        }
        FindIterable<Document> documents = collection.find(MongoDBConnection.toBson(template));
        MongoCursor<Document> cursor = documents.iterator();
        List<Document> list = new ArrayList<>();
        while (cursor.hasNext()) {
            Document document = new Document(cursor.next());
            document.put("_id", document.getObjectId("_id"));
//            System.out.println(document);
            list.add(document);
        }
        return list;
//        return StreamSupport.stream(
//                documents
//                        .map(d ->{
//                            d.put("_id",d.getObjectId("_id"));
//                            return d;
//                        })
//                        .spliterator(),true).collect(Collectors.toList());
    }


    @Override
    public Document save(Document document) {
        if (org.apache.commons.lang3.StringUtils.isNotEmpty(document.getObjectId("_id"))) {
            ObjectId _id = new ObjectId(document.getString("_id"));
            document.put("_id", _id);
        } else {
            document.put("_id", ObjectId.get());
        }
        collection.insertOne(document);
        return document;
    }

    @Override
    public Document update(Document document) {
        ObjectId _id = new ObjectId(document.getString("_id"));
        document.put("_id", _id);
        return collection.findOneAndReplace(Filters.eq("_id", document.getObjectId("_id")), document);
    }

    @Override
    public Document saveOrUpdate(Document document) {
        if (org.apache.commons.lang3.StringUtils.isNotEmpty(document.getObjectId("_id"))) {
            ObjectId _id = new ObjectId(document.getString("_id"));
            document.put("_id", _id);
            return new Document(collection.findOneAndReplace(
                    Filters.eq("_id", _id), document));
        }

        ObjectId _id = ObjectId.get();
        document.put("_id", _id);
        collection.insertOne(document);
        return document;
    }

    @Override
    public boolean deleteById(String _id) {
        return collection.findOneAndDelete(Filters.eq("_id", new ObjectId(_id))) != null;
    }
}
